package com.dlc.felear.xiaoensale.helper;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.dlc.felear.xiaoensale.constant.Constant;
import com.dlc.felear.xiaoensale.entity.StepMotorInfo;
import com.dlc.felear.xiaoensale.utils.RecordLog;
import com.dlc.felear.xiaoensale.utils.SendJbCmdUtil;

import org.simple.eventbus.EventBus;
import org.simple.eventbus.Subscriber;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

public class JiaoBanHelper implements Handler.Callback {
    private static final String TAG = "JiaoBanHelper";
    private static final int WHAT_CLOSE = 5143;
    private static final int WHAT_DELAY_CLOSE = 5144;
    private IoInputHelper inputHelper;
    private final byte io_sensor = 21;
    private final byte io_sensor2 = 20;
    private final byte io_sensor3 = 22;
    private final byte io_sensor4 = 24;
    private boolean isStop;
    private boolean isRun_360;
    private boolean yaobai = false;
    private Handler handler;
    private ScheduledExecutorService scheduledThreadPool;
    private boolean yaobaiStop = false;
    /**
     * 搅拌档位
     */
    private int lastSpeed = 0;
    private byte preSetSpeed = 1;
    private SendJbCmdUtil sendJbCmdUtil;
    private int funtion = 0;
    /**
     * 摇摆方式 false 通过限位  true 通过往返功能
     */
    private boolean yaobaiType = false;
    private List<Byte> tempList = new ArrayList<>(5);
    private GuotiHelper guotiHelper;

    public JiaoBanHelper(IoInputHelper inputHelper) {
        EventBus.getDefault().register(this);
        this.inputHelper = inputHelper;
        handler = new Handler(this);
        scheduledThreadPool = new ScheduledThreadPoolExecutor(4);
        sendJbCmdUtil = new SendJbCmdUtil(scheduledThreadPool);
    }

    public void setGuotiHelper( GuotiHelper guotiHelper){
        this.guotiHelper = guotiHelper;
    }


    public void stopJiaoban() {
        try {
            yaobai = false;
            isRun_360 = false;
            sendJbCmdUtil.setBooleanValue(false, false, false, false);
//            sendJbCmdUtil.setMotorStop();
            sendJbCmdUtil.setMotorSpeed((byte) 1);
            handler.sendEmptyMessageDelayed(WHAT_CLOSE, 8000);
            isStop = true;
        } catch (Exception e) {
        }
    }

    /**
     * 延迟停止搅拌
     */
    public void stopJiaobanDelay(int delayScon) {
        try {
            yaobai = false;
            isRun_360 = false;
            sendJbCmdUtil.setBooleanValue(false, false, false, false);
            handler.sendEmptyMessageDelayed(WHAT_DELAY_CLOSE, delayScon);
        } catch (Exception e) {

        }
    }


    /**
     * 数据判断
     *
     * @param value
     */
    public void paserData(byte value) {
        if (value > 3 || value < 0) {
            log("输入档位错误", 0);
            if (value == 10) {
                funtion = 0;
            } else if (value == 11) {
                funtion = 1;
            }
            return;
        }
        if (value == 0) {
            stopJiaoban();
        } else {
            startJaioban(value);
        }
    }

    /**
     * 降低搅拌速度
     *
     * @param value
     */
    public void jiangsu(byte value) {
        if (isRun_360) {
            sendJbCmdUtil.jiangsu(value);
        }
    }

    /**
     * 恢复减速前的搅拌速度
     */
    public void recoverSpeed() {
        log("恢复搅拌速度 lastSpeed=" + lastSpeed, 0);
        if (isRun_360) {
            sendJbCmdUtil.recoverSpeed();
        }
    }


    /**
     * 开始搅拌
     *
     * @param value
     */
    public void startJaioban(final byte value) {
        isStop = false;
        funtion = 1;
        preSetSpeed = value;
        if (funtion == 0) {
            rotate360(value, 2);
        } else {
            jbToLR(value);
        }
    }

    /**
     * 360度方式搅拌
     *
     * @param value
     * @param derect
     */
    private void rotate360(final byte value, final int derect) {
        log("档位:" + value, 0);
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    yaobai = false;
                    sendJbCmdUtil.setBooleanValue(true, false, false, false);
                    if (isRun_360) {
                        log("已经在搅拌", 0);
                        sendJbCmdUtil.setMotorSpeed(value);
                        return;
                    }
                    log("开始搅拌", 0);
                    sendJbCmdUtil.setMotorSpeed(value);
                    isRun_360 = true;
                    sendJbCmdUtil.setMotorPlus(0);
                    sendJbCmdUtil.zhengzhuanCmd();
                } catch (Exception e) {

                }
            }
        });
    }

    /**
     * 开始摇摆搅拌
     *
     * @param value
     */
    private void jbToLR(final byte value) {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    isStop = false;
                    preSetSpeed = value;
                    isRun_360 = false;
                    sendJbCmdUtil.setBooleanValue(false, true, false, false);
                    log("接收摇摆指令,jbToLR yaobai=" + yaobai + " 档位:" + value + " preSetSpeed=" + preSetSpeed, 0);
                    if (!yaobai) {
                        yaobai = true;
                        yaobaiStop = true;
                        if (inputHelper.getIoStatus(io_sensor3) == 1 && yaobaiType) {
                            log("已经在摇摆的位置X:22", 0);
                            yaobaiActionByReturn(2);
                            return;
                        }
                        if (inputHelper.getIoStatus(io_sensor2) == 1 && yaobaiType) {
                            log("已经在摇摆的位置X:20", 0);
                            yaobaiActionByReturn(1);
                            return;
                        }
                        log("旋转到摇摆的位置", 0);
                        sendJbCmdUtil.setMotorSpeed(value);
                        sendJbCmdUtil.setMotorPlus(0);
                        sendJbCmdUtil.zhengzhuanCmd();
                    }
                } catch (Exception e) {
                    log(e.getMessage(), 1);
                }
            }
        });
    }

    /**
     * 停止指令
     */
    public void stopCmd() {
        log("stopCmd isStop=" + isStop, 0);
        handler.removeMessages(WHAT_CLOSE);
        sendJbCmdUtil.setMotorStop();
    }

    /**
     * 洗锅搅拌
     *
     * @param msec
     */
    public void xiguoJiaoban(final int msec) {
        log("洗锅转动时间:" + msec, 0);
        isRun_360 = false;
        yaobai = false;
        sendJbCmdUtil.setBooleanValue(false, false, true, false);
        sendJbCmdUtil.setMotorSpeed((byte) 1);
        sendJbCmdUtil.setMotorPlus(0);
        sendJbCmdUtil.zhengzhuanCmd();
    }

    /**
     * 出锅倒菜搅拌
     *
     * @param second
     */
    public void chuguoJiaoban(int second) {
        log("出锅搅拌:" + second, 0);
        isRun_360 = false;
        yaobai = false;
        sendJbCmdUtil.setBooleanValue(false, false, false, true);
        sendJbCmdUtil.setMotorSpeed((byte) 1);
        sendJbCmdUtil.setMotorPlus(0);
        sendJbCmdUtil.fanzhuanCmd();
    }

    @Override
    public boolean handleMessage(final Message msg) {
        switch (msg.what) {
            case WHAT_CLOSE:
                stopCmd();
                break;
            case WHAT_DELAY_CLOSE:
                isStop = true;
                handler.sendEmptyMessageDelayed(WHAT_CLOSE, 2000);
                break;
        }
        return false;
    }


    /**
     * 接受串口信息
     *
     * @param data
     */
    public void reviceData(byte[] data) {
        EventBus.getDefault().post(data, Constant.STEP_MOTOR_RESULT);
        sendJbCmdUtil.reviceData(data);
    }

    private int tempIndex = 20;

    /**
     * 搅拌器位置反馈
     *
     * @param position
     */
    public void sensorStatus(final byte position) {
//        log("触发开关: isStop=" + isStop + " X=" + position);
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                switch (position) {
                    case io_sensor:
                        log("触发开关: isStop=" + isStop + " X=" + position, 0);
//                        addPosition(position);
                        position();
                        tempIndex = position;
                        break;
                    case io_sensor2:
                        log("触发开关: isStop=" + isStop + " X=" + position, 0);
//                        openIo(32);
                        addPosition(position);
                        if (!isStop) {
                            changeSpeed(1);
                        }
                        tempIndex = position;
                        break;
                    case io_sensor3:
//                        openIo(33);
                        addPosition(position);
                        log("触发开关: isStop=" + isStop + " X=" + position, 0);
                        if (!isStop) {
                            changeSpeed(2);
                        }
                        tempIndex = position;
                        break;
                    case io_sensor4:
                        log("触发开关: isStop=" + isStop + " X=" + position, 0);
                        addPosition(position);
                        if (!isStop) {
//                            stop_run();
                        }
                        tempIndex = position;
                        break;

                }
            }
        });
    }

    private void stop_run() {
        int p=getPositon();
        p=-1;
        if(p!=-1){
            if (yaobai && p==1) {
                log("1zhengzhuanCmd tempIndex=" + tempIndex + " preSetSpeed=" + preSetSpeed, 0);
                sendJbCmdUtil.setMotorStop();
                sendJbCmdUtil.setMotorSpeed(preSetSpeed);
                sendJbCmdUtil.zhengzhuanCmd();
            } else if (yaobai && p==2) {
                log("1fanzhuanCmd tempIndex=" + tempIndex + " preSetSpeed=" + preSetSpeed, 0);
                sendJbCmdUtil.setMotorStop();
                sendJbCmdUtil.setMotorSpeed(preSetSpeed);
                sendJbCmdUtil.fanzhuanCmd();
            }
        }else {
            if (yaobai && tempIndex == io_sensor3) {
                log("zhengzhuanCmd tempIndex=" + tempIndex + " preSetSpeed=" + preSetSpeed, 0);
                sendJbCmdUtil.setMotorStop();
                sendJbCmdUtil.setMotorSpeed(preSetSpeed);
                sendJbCmdUtil.zhengzhuanCmd();
            } else if (yaobai && tempIndex == io_sensor2) {
                log("fanzhuanCmd tempIndex=" + tempIndex + " preSetSpeed=" + preSetSpeed, 0);
                sendJbCmdUtil.setMotorStop();
                sendJbCmdUtil.setMotorSpeed(preSetSpeed);
                sendJbCmdUtil.fanzhuanCmd();
            }
        }

    }

    /**
     * 搅拌为摇摆时 执行摇摆逻辑
     *
     * @param flag
     */
    private void changeSpeed(int flag) {
        if (!yaobai) {
            return;
        }
        if (yaobaiType) {
            yaobaiActionByReturn(flag);
        } else {
            yaobaiActionBySwitch(flag);
        }
    }

    /**
     * 通过限位位置指令实现搅拌摇摆
     *
     * @param flag
     */
    private void yaobaiActionBySwitch(final int flag) {
        sendJbCmdUtil.setMotorSpeed((byte) 1);
        if (flag == 2) {
            log("正转", 0);
            sendJbCmdUtil.zhengzhuanCmd();
        } else {
            log("反转", 0);
            sendJbCmdUtil.fanzhuanCmd();
        }
    }

    /**
     * 通过摇摆指令实现搅拌摇摆
     *
     * @param flag
     */
    private void yaobaiActionByReturn(final int flag) {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    log("摇摆动作:" + yaobaiStop + " 方向 flag=" + flag, 0);
                    if (yaobaiStop) {
                        yaobaiStop = false;
                        sendJbCmdUtil.setMotorStop();
                        sendJbCmdUtil.setMotorSpeed(preSetSpeed);
                        sendJbCmdUtil.setMotorRepet(700, flag);
                    }
                } catch (Exception e) {

                }
            }
        });
    }

    /**
     * 搅拌器触发原点处理逻辑
     */
    private void position() {
        scheduledThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                sendJbCmdUtil.setlastTimeRecord(System.currentTimeMillis());
                if (isStop) {
                    stopCmd();
                } else if (isRun_360 || yaobai) {
                    initSpeed();
                }
            }
        });
    }

    /**
     * 搅拌变速
     */
    private void initSpeed() {
        if (sendJbCmdUtil.getCurrentSpeed() > 0 &&
                (sendJbCmdUtil.getAngleByLevel(preSetSpeed) != sendJbCmdUtil.getCurrentSpeed())) {
            sendJbCmdUtil.setMotorSpeed(preSetSpeed);
        }
    }

    private void log(String msg, int level) {
        if (level == 1) {
            RecordLog.getInstance().saveLog(msg);
        }
        Log.e(TAG, msg);
    }

    @Subscriber(tag = Constant.STEP_MOTOR_CMD)
    private void recieveCmd(StepMotorInfo stepMotorInfo) {
        log("步进电机调试：" + JsonHelper.toJson(stepMotorInfo), 0);
        sendJbCmdUtil.recieveCmd(stepMotorInfo);
    }

    public void immediatelyStop() {
        sendJbCmdUtil.setMotorStop();
    }

    private void addPosition(byte position) {
        log("position=" + position, 0);
        if (tempList.size() <= 3) {
            tempList.add(position);
        } else {
            tempList.remove(0);
            tempList.add(position);
        }
        log("tempList=" + JsonHelper.toJson(tempList), 0);
        //21 22 24  21 20 24
    }

    private int getPositon() {
        int temp = -1;
        int szie = tempList.size();
        if (szie < 1) {
            return temp;
        }
        byte temp1 = tempList.get(szie-1);
        if((temp1==24&&tempList.get(szie-2)==22)||(temp1==24&&tempList.get(szie-2)==21&&tempList.get(szie-3)==20)){
            temp=1;
        }else if((temp1==24&&tempList.get(szie-2)==20)||(temp1==24&&tempList.get(szie-2)==21&&tempList.get(szie-3)==22)){
            temp=2;
        }
        return temp;
    }


    private void openIo(int num){
        guotiHelper.controlOutputIo((byte) num,255,500);
    }

}


